
<template>
 
<div class="">
  <div class="div">
    <el-text class="text">LayaAir.d.ts路径：</el-text>
  </div>
  <el-input v-model="inputLib" style="width: 500px" placeholder="Please input" />
  <el-button style="margin-left: 10px" @click="onLibExeClick">加载并解析</el-button>
  <el-button @click="onLibParserClick">解析</el-button>

  <div class="div">
    <el-text class="text">源路径：</el-text>
  </div>
  <el-input v-model="input" style="width: 500px" placeholder="Please input" />
  <el-button style="margin-left: 10px" @click="onExeClick">加载</el-button>

  <div class="div">
    <el-text class="text">转换路径：</el-text>
  </div>
  <el-input v-model="input2" style="width: 500px" placeholder="Please input" />
  
  <div class="div">
    <el-button @click="onFindVars">解析</el-button>
    <el-button @click="onTestClick">转换</el-button>
    <el-text class="text" style="margin-left: 30px;">{{ infoTxt }}</el-text>
  </div>
</div>
 
 
</template>

<script setup lang="ts">

import { ref, onMounted } from 'vue'

import SelectRoleResConst from './Test';

console.log('类型打印：',SelectRoleResConst.FGMUI_MLOADING);
console.log('类型打印：' + SelectRoleResConst.FGMUI_MLOADING);

const nw = window.nw;

const inputLib = ref('D:/work/layabox/test3.0-1/LayaProject/engine/types/LayaAir.d.ts');
const input = ref('D:/work/layabox/qiannian/code/client/TuLong2/modules/selectRole/src')
const input2 = ref('C:/Users/A/Desktop/out')
const infoTxt = ref('')

const fs = nw.require('fs');
const path = nw.require('path');

// const fileArr:any[] = [];
const fileTxtArr:any[] = [];
const fileDataArr:any = {};//路径为key，
let fileCount:number = 1;
let isRunning:boolean = false;
const valueTypes:string[] = ['int', 'Boolean', 'String'];
const asTypeDic:any = {'int':'number', 'uint':'number', 'Number':'number', 'Boolean':'boolean', 'String':'string', 'Object':'any', 'Class':'any', '*':'any', 'Array':'any[]', 'void':'void'};//

onMounted(() => {

  setInterval(() => {
    onExeTransfer();
  }, 30);
})

async function onExeTransfer(){
  if(isRunning){
    if(fileTxtArr.length <= 0){
      isRunning = false;
      console.log('全部转换完成:' + ((fileCount - fileTxtArr.length) + '/' + fileCount)); 
      return;
    }
    // 读取文件sample.html
    let info:any = fileTxtArr.pop();
    infoTxt.value = '进度：' + (fileCount - fileTxtArr.length) + '/' + fileCount;
    await fs.readFile(info.path, 
        // 读取文件完成时调用的回调函数
        function(err:any, data:any) {  
            if (err) {
              console.error('readFile error!', err);
            }
            // 数据是包含文件内容的缓冲区
            var content:string = data.toString('utf8');
            try{
              transferSingle(info.path, content);
            }
            catch(error:any){
              console.error(error);
            }
    });
  }
}
//文件内容的转换处理
function transferSingle(path:string, content:string){
  path = path.replace(/\\/g, '/');
  let inputValue:string = input.value;
  inputValue = inputValue.replace(/\\/g, '/');
  let rt:string = inputValue.substring(inputValue.lastIndexOf('/')); 
  rt = '/' + rt;
  let p1:string = path.replace(inputValue, '');

  p1 = p1.replace("\.as", '\.ts');
  p1 = input2.value + rt + p1;
  // console.log('out print:',p1);
  let dir:string = p1.substring(0, p1.lastIndexOf('/'));

  fs.mkdir(dir, { recursive: true }, function(err:any){
    if (err) {
        console.error('dir error!',err);
    }
    // console.log("目录创建成功。", dir);

    content = contentTransfer(p1, content);
    // 具有文件名，内容和回调函数的writeFile函数
    fs.writeFile(p1, content, function (err1:any) { 
      if (err1) {
        console.error('write error!', p1)
      }
      console.log('File is created successfully.' + ((fileCount - fileTxtArr.length) + '/' + fileCount), p1); 
    });
  })
}
/** 
 * 内容的转换 核心 
 * @param path :导出的全路径
*/
function contentTransfer(path:string, content:string):string{
  let temp:string = content;
  let index1:number = temp.indexOf('package');
  if(index1 != -1 && index1 < 50){//随便写的一个数字，为了判断属于as的包名称
    let index2:number = temp.indexOf('{');
    let index3:number = temp.lastIndexOf('}');
    temp = temp.substring(index2 + 1, index3);

    let replaceArr:any[] = [];//集中替换
    //import导包处理
    let importFix:string = '';
    index2 = temp.indexOf('import ');
    let importDic:any = {};//导入的包 做记录，后面用于每行检查判断。
    while(index2 != -1){
      importFix = getImportFix(path);

      index3 = temp.indexOf('\r', index2);
      let linestr:string = temp.substring(index2, index3);
      linestr = linestr.replace(/;/g, '');
      let newImport:string = '';
      
      let arr:string[] = linestr.split('\.');
      let importName:string = arr[arr.length - 1];
      arr = linestr.split(' ');//暂时以空格判断

      if(linestr.indexOf('laya\.') != -1){//说明是laya的包
        //import Button = Laya.Button;
        newImport = 'import ' + importName + ' = ' + 'Laya.' + importName + '';
      }
      else{//其它的导包
        let importPath = arr[1].replace(/\./g, '/');
        newImport = arr[0] + ' ' + importName + ' from ' + '"' +  importFix + importPath + '"';
      }
      if(importDic[importName] != null){//如果已存在。
        newImport = '//';
      }
      replaceArr.push({source:linestr, target:newImport});
      importDic[importName] = true;
      
      index2 = temp.indexOf('import ', index3-2);
    }

    //类名，构造函数处理------------
    let arr:string[] = path.split('/');
    let className:string = arr[arr.length - 1];
    className = className.replace('\.ts', '');
    console.log('正在转换--------->', className);
    
    //构造函数
    index1 = temp.indexOf('public class ');
    if(index1 != -1){
      temp = replaceConstructor(temp, index1, className);
    }

    let index12:number = temp.indexOf('class ', index1 + 30);//内部类
    let hasInner:boolean = false;
    let tempIndex:number = index12;
    while(tempIndex != -1){
      hasInner = true;
      temp = replaceConstructor(temp, tempIndex, className);
      tempIndex = temp.indexOf('class ', tempIndex + 20);//内部类
    }
    //结尾'}'处理
    if(index1 != -1 && hasInner){//有的类只有个内部类。。。。
      let kh:number = temp.lastIndexOf('}', index12);
      let khStr1:string = temp.substring(0, kh);
      let khStr2:string = temp.substring(kh + 1);
      temp = khStr1 + khStr2 + '}\r\n///////end///////\r\n';
    }
    
    temp = temp.replace('public class ', 'export default class ');//类名
    // temp = temp.replace('class ', 'export default class-- ');//内部类，这个不用更换
    
    //
    
    //执行替换
    let replaceIndex:number = 0;
    let info:any;
    for(var i=0; i<replaceArr.length; i++){
      info = replaceArr[i];
      temp = temp.replace(info.source, info.target);
    }

    //逐行检查
    let keyStr:string = path.split('/src/')[1];
    keyStr = keyStr.replace('\.ts', '');
    let parserInfo:any = fileDataArr[keyStr];
    let statics:string[] = parserInfo.statics;
    if(keyStr.indexOf('UtilAStar') != -1){
      console.log('局部变量调试1：',keyStr);
    }

    let tempInfo:any = {vars:parserInfo.var.concat(), funs:parserInfo.fun.concat()};
    //继续递归查询继承的父类数据，然后做融合处理。
    checkFatherVars(tempInfo, temp);
    let vars:string[] = tempInfo.vars;
    let funs:string[] = tempInfo.funs;
    let locals:string[] = parserInfo.local;

    let lineArr:string[] = [];
    index1 = 0;
    index2 = temp.indexOf('\n', index1 + 1);
    while(index2 != -1){
      let lstr:string = temp.substring(index1, index2);
      let trimStr:string = lstr.trim();
      lineArr.push(lstr);
      index1 = index2;
      index2 = temp.indexOf('\n', index1 + 1);
    }
    temp = '';
    let addImportDic:any = {};//需要补齐的import

    for(i=0; i<lineArr.length; i++){//逐行检查

      let lineStr:string = lineArr[i];
      let lineTemp:string = lineStr;
      let trimStr:string = lineTemp.trim();

      if(lineTemp.match("(?=.*[a-zA-Z].*)") && trimStr.indexOf('//') != 0){
        let idx1:number = lineTemp.indexOf('public ');
        let idx2:number = lineTemp.indexOf('private ');
        let idx3:number = lineTemp.indexOf('protected ');
        let idx4:number = lineTemp.indexOf('import ');
        if(idx1 == -1 && idx2 == -1 && idx3 == -1){
          //检查成员变量、方法的调用，补上 this. 调用。
          lineTemp = checkSetThis(vars, lineTemp, locals, i + 1);
          lineTemp = checkSetThis(funs, lineTemp);
          lineTemp = checkSetStatic(statics, lineTemp, className);

          if(idx4 == -1){
            lineTemp = checkAddImport(importDic, addImportDic, lineTemp, keyStr, className);
            lineTemp = checkAddImport2(importDic, addImportDic, lineTemp, keyStr, className);
            lineTemp = checkAddImport3(importDic, addImportDic, lineTemp, keyStr, className);
          }
        }
        else{
          if(idx4 == -1){
            lineTemp = checkSetStatic(statics, lineTemp, className);
            lineTemp = checkAddImport(importDic, addImportDic, lineTemp, keyStr, className);
            lineTemp = checkAddImport2(importDic, addImportDic, lineTemp, keyStr, className);
            lineTemp = checkAddImport3(importDic, addImportDic, lineTemp, keyStr, className);
          }
        }
        //set 函数去掉后面的 :void
        lineTemp = replaceBySetFun(lineTemp);
        lineArr[i] = lineTemp;
      }
      else{
        // console.log('不包含', lineStr);
      }
      temp += lineTemp;
    }
    
    //补上import
    index1 = 0;
    index2 = temp.lastIndexOf('\r', index1);
    let str1:string = temp.substring(0, index2);
    let str2:string = '';
    for(var key in addImportDic){
      str2 += addImportDic[key];
    }
    str2 += '\r\n';
    let str3 = temp.substring(index2);
    temp = str1 + str2 + str3;

    //for each替换
    temp = replaceForEach(temp);
    temp = temp.replace(/ is /g, ' instanceof ');
    

    //成员变量
    temp = temp.replace(/public var /g, 'public ');
    temp = temp.replace(/private var /g, 'private ');
    temp = temp.replace(/protected var /g, 'protected ');
    
    temp = temp.replace(/public static var /g, 'public static ');
    temp = temp.replace(/private static var /g, 'private static ');
    temp = temp.replace(/protected static var /g, 'protected static ');
    
    temp = temp.replace(/public static const /g, 'public static ');
    temp = temp.replace(/private static const /g, 'private static ');
    temp = temp.replace(/protected static const /g, 'protected static ');
    
    //成员方法
    temp = temp.replace(/public function /g, 'public ');
    temp = temp.replace(/private function /g, 'private ');
    temp = temp.replace(/protected function /g, 'protected ');

    temp = temp.replace(/public static function /g, 'public static ');
    temp = temp.replace(/private static function /g, 'private static ');
    temp = temp.replace(/protected static function /g, 'protected static ');
    
    temp = temp.replace(/public override function /g, 'public override ');
    temp = temp.replace(/override public function /g, 'public override ');

    temp = temp.replace(/private override function /g, 'private override ');
    temp = temp.replace(/override private function /g, 'private override ');

    temp = temp.replace(/protected override function /g, 'protected override ');
    temp = temp.replace(/override protected function /g, 'protected override ');
  }
  return temp;
}
function replaceBySetFun(lineTemp:string):string
{
  let idx:number = lineTemp.indexOf(' set ');
  if(idx != -1){
    lineTemp = lineTemp.replace(':void', '');
  }
  return lineTemp;
}
/** for each替换为 .forEach() */
function replaceForEach(temp:string):string{
  let idx1:number = temp.indexOf('for each');
  while(idx1 != -1){
    if(leftIsEmpty(temp, idx1)){
      let endIndex:number = matchBraces(temp, idx1);
      if(endIndex != -1){
        let str1:string = temp.substring(0, idx1);
        let str2:string = temp.substring(idx1, endIndex);
        let str3:string = temp.substring(endIndex);

        let linePoint:number = str2.indexOf('\n');
        let lineStr1:string = str2.substring(0, linePoint);
        let lineStr2:string = str2.substring(linePoint);
        let newLine:string;
        let varName:string = lineStr1.split(' in ')[1];
        varName = varName.split(')')[0];
        varName = varName.trim();
        let paramName:string = lineStr1.split(' in ')[0];
        paramName = paramName.split('(')[1];
        paramName = paramName.replace('var ', '');

        let khStr:string = '';
        if(lineStr1.indexOf('{') != -1){
          khStr = '{';
        }
        lineStr1 = varName + '.forEach((' + paramName + ') => ' + khStr;
        lineStr2 += ');';

        str2 = lineStr1 + lineStr2;
        temp = str1 + str2 + str3;


        //ts
        // this.arrBtnSex.forEach((btn: Button) => {
				//   btn.off(Event.CLICK,this,this.onBtnSexClick)
        // });

        //as3.0
        // for each (var btn:Button in this.arrBtnSex) 
        // {
        //   btn.off(Event.CLICK,this,this.onBtnSexClick)
        // }
      }
    }
    idx1 = temp.indexOf('for each', idx1 + 10);
  }
  return temp;
}
function leftIsEmpty(temp:string, idx:number):boolean{
  let checkIdx:number = temp.lastIndexOf('\n', idx);
  let checkStr:string = temp.substring(checkIdx, idx);
  return Boolean(checkStr.trim() == '');
}
function matchBraces(input: string, start:number): number {
    let startIndex = input.indexOf('{', start);
    if (startIndex === -1) {
        return -1; // 没有找到开始的 '{'
    }

    let endIndex = -1;
    let braceCount = 1; // 初始化括号计数器为1，因为我们已经找到了第一个 '{'

    // 从startIndex的下一个位置开始遍历
    for (let i = startIndex + 1; i < input.length; i++) {
        if (input[i] === '{') {
            braceCount++; // 遇到 '{' 增加计数器
        } else if (input[i] === '}') {
            braceCount--; // 遇到 '}' 减少计数器

            if (braceCount === 0) {
                endIndex = i; // 当计数器为0时，找到了对应的 '}'
                break;
            }
        }
    }

    // 如果没有找到对应的 '}'，返回null
    if (endIndex === -1) {
        return -1;
    }

    // 返回匹配到的内容
    // return input.slice(startIndex, endIndex + 1);
    return endIndex + 1;
}
/** 递归追溯继承的父类，整合所有的成员变量、函数 */
function checkFatherVars(tempInfo:any, temp:string){
  let vars:string[] = tempInfo.vars;
  let funs:string[] = tempInfo.funs;
  let extStart:number = 0;
  let extendsIdx:number = temp.indexOf(' extends ', extStart);
  while(extendsIdx != -1){
    let extEnd1:number = temp.indexOf('\r', extendsIdx + 9);
    let extEnd2:number = temp.indexOf(' ', extendsIdx + 9);
    let extEnd:number = Math.min(extEnd1, extEnd2);
    let extName:string = temp.substring(extendsIdx + 9, extEnd);

    let iptIdx:number = temp.indexOf('import ' + extName + ' ', extStart);
    if(iptIdx != -1){
      let iptEnd:number = temp.indexOf(';', iptIdx + 10);
      let iptStr:string = temp.substring(iptIdx, iptEnd);
      if(iptStr.indexOf('Laya\.') != -1){//继承的是laya底层的类
        //得给laya提供个路径输入框
        //do something...
        checkFatherVarsByLaya(tempInfo, extName);
      }
      else{//继承的是自定义类
        let iptArr:string[] = iptStr.split('"');
        let ppath:string = iptArr[1];
        ppath = ppath.replace(/\.\.\//g, '');
        let pInfo:any = fileDataArr[ppath];
        if(pInfo){
          tempInfo.vars = vars.concat(pInfo.var);
          tempInfo.funs = funs.concat(pInfo.fun);

          checkFatherVars(tempInfo, pInfo.content);
        }
      }
    }
    extStart = extendsIdx + 20;
    extendsIdx = temp.indexOf(' extends ', extStart);
  }
}
function checkFatherVarsByLaya(tempInfo:any, layaClsName:string){
  let vars:string[] = tempInfo.vars;
  let funs:string[] = tempInfo.funs;
  let pInfo:any = fileDataArr[layaClsName];
  if(pInfo){
    tempInfo.vars = vars.concat(pInfo.var);
    tempInfo.funs = funs.concat(pInfo.fun);
    if(pInfo.father != null && pInfo.father != ''){
      checkFatherVarsByLaya(tempInfo, pInfo.father);
    }
  }
}
function checkAddImport(importDic:any, addDic:any, lineTemp:string, keyStr:string, curClass:string):string{
  let idx1:number = lineTemp.indexOf(':');
  if(curClass.indexOf('TLPool') != -1 && lineTemp.indexOf('getObj(') != -1){
    console.log('类型替换调试：', curClass, lineTemp);
  }
  while(idx1 != -1){
    let start:number = idx1 + 1;
    let end:number = start + 1;
    for(var i=start+1; i<=lineTemp.length-1; i++){
      let char:string = lineTemp.substring(i, i+1);
      if(char.match("(?=.*[a-zA-Z].*)") || char == '_' || char == '*'){
        if(i == lineTemp.length-1){
          end = i + 1;
          break;
        }
      }
      else{
        end = i;
        break;
      }
    }
    
    let parserInfo:any = fileDataArr[keyStr];
    let classArr:string[] = parserInfo.classArr;

    let clsName:string = lineTemp.substring(start, end);
    clsName = clsName.trim();
    let first:string = clsName.substring(0, 1);
    if(!first.match("(?=.*[A-Z].*)") && asTypeDic[clsName] == null){
      idx1 = lineTemp.indexOf(':', end);
      continue;
    }
    if(clsName == ''){
      idx1 = lineTemp.indexOf(':', end);
      continue;
    }
    if(classArr.indexOf(clsName) != -1 || clsName == 'this' || clsName == 'Math' || clsName == 'Laya' ||  clsName == 'Date'){
      idx1 = lineTemp.indexOf(':', end);
      continue;
    }
    if(importDic[clsName] == null){//不存在导包
      let typeStr:string = asTypeDic[clsName];
      if(typeStr != null){//as3内置类型，直接进行替换。
        let s1:string = lineTemp.substring(0, start);
        let s2:string = typeStr;
        let s3:string = lineTemp.substring(end);
        lineTemp = s1 + s2 + s3;
      }
      else{
        let newKey:string = keyStr.replace(curClass, '');
        newKey += clsName;
        let fix:string = '';
        let importLine:string = '';
        if(fileDataArr[newKey] != null){//当前目录找一找 
          if(addDic[newKey] == null){
            fix = getImportFix2(keyStr);
            importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
            addDic[newKey] = importLine;
          }
        }
        else{//那应该是src下的默认目录
          newKey = clsName;
          // if(fileDataArr[newKey] != null){
            if(addDic[newKey] == null){
              fix = getImportFix2(keyStr);
              importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
              addDic[newKey] = importLine;
            }
          // }
        }
      }
    }
    idx1 = lineTemp.indexOf(':', idx1 + 2);
  }
  return lineTemp;
}
function checkAddImport2(importDic:any, addDic:any, lineTemp:string, keyStr:string, curClass:string):string{
  let idx1:number = lineTemp.lastIndexOf('.');
  while(idx1 != -1){
    let start:number = idx1 - 1;
    let end:number = start - 1;
    for(var i=start; i>0; i--){
      let char:string = lineTemp.substring(i, i+1);
      if(char.match("(?=.*[a-zA-Z].*)") || char == '_'){

      }
      else{
        if(char != '.' && char != '/' && char != '\\'){
          end = i + 1;
        }
        else{
          end = -1;
        }
        break;
      }
    }
    if(end == -1){
      idx1 = lineTemp.lastIndexOf('.', start);
      continue;
    }
    start += 1;

    let parserInfo:any = fileDataArr[keyStr];
    let classArr:string[] = parserInfo.classArr;

    let clsName:string = lineTemp.substring(end, start);
    let first:string = clsName.substring(0, 1);
    if(!first.match("(?=.*[A-Z].*)") && asTypeDic[clsName] == null){
      idx1 = lineTemp.lastIndexOf('.', end-2);
      continue;
    }
    if(clsName == ''){
      idx1 = lineTemp.lastIndexOf('.', end-2);
      continue;
    }
    if(classArr.indexOf(clsName) != -1 || clsName == 'this' || clsName == 'Math' || clsName == 'Laya' ||  clsName == 'Date'){
      idx1 = lineTemp.lastIndexOf('.', end-2);
      continue;
    }
    if(importDic[clsName] == null){//不存在导包
      let typeStr:string = asTypeDic[clsName];
      if(typeStr != null){//as3内置类型，直接进行替换。
        //不要处理，一般都是调用静态方法。
        // let s1:string = lineTemp.substring(0, end);
        // let s2:string = typeStr;
        // let s3:string = lineTemp.substring(start);
        // lineTemp = s1 + s2 + s3;
      }
      else{
        let newKey:string = keyStr.replace(curClass, '');
        newKey += clsName;
        let fix:string = '';
        let importLine:string = '';
        if(fileDataArr[newKey] != null){//当前目录找一找 
          if(addDic[newKey] == null){
            fix = getImportFix2(keyStr);
            importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
            addDic[newKey] = importLine;
          }
        }
        else{//那应该是src下的默认目录
          newKey = clsName;
          // if(fileDataArr[newKey] != null){
            if(addDic[newKey] == null){
              fix = getImportFix2(keyStr);
              importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
              addDic[newKey] = importLine;
            }
          // }
        }
      }
    }
    idx1 = lineTemp.lastIndexOf('.', end-2);
  }
  return lineTemp;
}
function checkAddImport3(importDic:any, addDic:any, lineTemp:string, keyStr:string, curClass:string):string
{
  let idx:number = lineTemp.indexOf(' extends ');
  if(idx != -1){
    let clsName:string = lineTemp.split(' extends ')[1];
    clsName = clsName.trim();
    if(importDic[clsName] == null){
      if(addDic[clsName] == null){
        let newKey:string = keyStr.replace(curClass, '');
        newKey += clsName;
        let fix:string = '';
        let importLine:string = '';
        if(fileDataArr[newKey] != null){//当前目录找一找 
          if(addDic[newKey] == null){
            fix = getImportFix2(keyStr);
            importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
            addDic[newKey] = importLine;
          }
        }
        else{//那应该是src下的默认目录
          newKey = clsName;
          // if(fileDataArr[newKey] != null){
            if(addDic[newKey] == null){
              fix = getImportFix2(keyStr);
              importLine = '\r\nimport ' + clsName + ' from "' + fix + newKey + '";';
              addDic[newKey] = importLine;
            }
          // }
        }
      }
    }
  }
  return lineTemp;
}
/** 给成员变量、函数的调用，加上this.域指定 */
function checkSetThis(names:string[], lineTemp:string, locals:any = null, lineIndex:number = 0):string{
  // 正则表达式，匹配 {} 内的内容
  const regex = /{([^}]+)}/g;
  let match;
  let khArr:string[] = [];
  while ((match = regex.exec(lineTemp)) !== null) {
      // 匹配到的内容在 match[1] 中
      // console.log(match[1]);
      khArr.push(match[1]);
  }
  let leftSpace:number = getLeftSpace(lineTemp);

  for(var j=0; j<names.length; j++){
    let start:number = 0;
    let idx1:number = lineTemp.indexOf(names[j]);
    while(idx1 != -1 && idx1 > 0){
      let s1:string = lineTemp.substring(idx1-1, idx1);
      let end:number = idx1+names[j].length;
      let s2:string = lineTemp.substring(end, end+1);
      let s3:string;
      let step:number = 1;

      let isKhVar:boolean = false;
      for(var i=0; i<khArr.length; i++){
        if(khArr[i].indexOf(names[j]) != -1){
          isKhVar = true;
          break;
        }
      }
      let isLocal:boolean = false;
      if(locals){//判断是否是局部变量
        if(lineTemp.indexOf('G') != -1){
          console.log('局部变量调试2：', lineTemp);
        }
        let startLine:number = lineIndex;
        let endLine:number = startLine - 30;
        if(endLine < 0) endLine = 0;
        for(var h=startLine; h>=endLine; h--){
          if(locals[h] != null){
            let curArr:any[] = locals[h];
            for(var k=0; k<curArr.length; k++){
              if(curArr[k].var == names[j] && leftSpace >= curArr[k].left){
                isLocal = true;
                break;
              }
            }
            if(isLocal){
              break;
            }
          }
        }
      }
      let flag1:boolean = Boolean(s1 != '.');
      let flag2:boolean = Boolean(s2 != ':');

      if(!isLocal && flag2 && flag1 && !isKhVar && !s1.match("(?=.*[a-zA-Z].*)") && s1.indexOf('_') == -1 && !s2.match("(?=.*[a-zA-Z].*)") && s2.indexOf('_') == -1){//说明是成员变量的调用
        s1 = lineTemp.substring(idx1-6, idx1);
        if(s1.indexOf('this\.') == -1 && s1.indexOf('super\.') == -1){
          s1 = lineTemp.substring(start, idx1);
          s2 = 'this.' + names[j];
          s3 = lineTemp.substring(end);
          lineTemp = s1 + s2 + s3;
          step = 6;
        }
      }
      idx1 = lineTemp.indexOf(names[j], idx1 + step);
    }
  }
  return lineTemp;
}
/** 给静态 成员变量、函数的调用，加上域指定 */
function checkSetStatic(names:string[], lineTemp:string, clsName:string):string{
  // if(clsName.indexOf('BitTool') != -1 && lineTemp.indexOf('HiByte') != -1){
  //   console.log('静态变量替换调试：', clsName, lineTemp);
  // }
  for(var j=0; j<names.length; j++){
    let start:number = 0;
    let idx1:number = lineTemp.indexOf(names[j]);
    while(idx1 != -1){
      let s1:string = lineTemp.substring(idx1-1, idx1);
      let end:number = idx1+names[j].length;
      let s2:string = lineTemp.substring(end, end+1);
      let s3:string;
      let step:number = 1;
      
      let leftStr:string = lineTemp.substring(idx1-10, idx1);
      let flag1:boolean = leftStr.indexOf('const ') == -1;
      let flag2:boolean = leftStr.indexOf('function ') == -1;
      let flag3:boolean = leftStr.indexOf('var ') == -1;
      let flag4:boolean = leftStr.indexOf('get ') == -1;
      let flag5:boolean = s1 != '.';
      
      if(flag5 && flag4 && flag3 && flag1 && flag2 && !s1.match("(?=.*[a-zA-Z].*)") && s1.indexOf('_') == -1 && !s2.match("(?=.*[a-zA-Z].*)") && s2.indexOf('_') == -1){//说明是成员变量的调用
        s1 = lineTemp.substring(idx1 - clsName.length - 1, idx1);
        if(s1.indexOf(clsName + '\.') == -1){
          s1 = lineTemp.substring(start, idx1);
          s2 = clsName + '.' + names[j];
          s3 = lineTemp.substring(end);
          lineTemp = s1 + s2 + s3;
          step = clsName.length + 1;
        }
      }
      idx1 = lineTemp.indexOf(names[j], idx1 + step);
    }
  }
  return lineTemp;
}
function replaceConstructor(temp:string, start:number, className:string):string{
  let index2:number = temp.indexOf('public function ', start);
  let index4:number = index2;
  let arr:string[];
  let arr2:string[];
  if(index2 != -1){
    if(temp.indexOf(' extends ') != -1){//构造函数里补上 super();
      let flag:boolean = true;
      while(flag){
        let index3:number = temp.indexOf('}', index4);
        let checkStr:string = temp.substring(index2, index3+2);
        arr = checkStr.split('{');
        arr2 = checkStr.split('}');
        if(arr.length != arr2.length){
          index4 = index3 + 1;
        }
        else{
          flag = false;
          let cstStr:string = temp.substring(index2, index3);//截取构造函数的内容
          if(cstStr.indexOf('super(') == -1){//没有调用super，则补上。
            index3 = temp.indexOf('{', index2);
            let str1:string = temp.substring(0, index3 + 1);
            let str2:string = 'super();';
            let str3:string = temp.substring(index3 + 1);
            temp = str1 + str2 + str3;
          }
          
          break;
        }
      }
    }
    
    let idx:number = temp.indexOf('\r', start);
    let str:string = temp.substring(start, idx);
    arr = str.split('class ');
    str = arr[1];
    arr = str.split(' ');
    str = arr[0];
    if(className.indexOf('UtilAStar') != -1){
      console.log('内部类构造调试：',className);
    }
    className = str;
    className = className.trim();
    temp = temp.replace('public function ' + className, 'constructor');//构造函数
  }
  return temp;
}
function getImportFix(path:string):string{
  let arr:string[] = path.split('/');
  let fix:string = '';
  for(var i=arr.length-2; i>0; i--){
    if(arr[i] == 'src'){
      break;
    }
    else{
      fix += '../';
    }
  }
  if(fix == ''){
    fix = './';
  }
  return fix;
}
function getImportFix2(keyStr:string):string{
  let arr:string[] = keyStr.split('/');
  let fix:string = '';
  for(var i=1; i<arr.length; i++){
    fix += '../';
  }
  if(fix == ''){
    fix = './';
  }
  return fix;
}
function onLibParserClick(){

}
function onLibExeClick(){
  let inputValue:string = inputLib.value;
  inputValue = inputValue.replace(/\\/g, '/');
  fs.readFile(inputValue, 
    // 读取文件完成时调用的回调函数
    function(err:any, data:any) {  
      if (err) throw err; 
      // 数据是包含文件内容的缓冲区
      var content:string = data.toString('utf8');
      
      saveLibVars222(content);
  });
}
function saveLibVars222(content:string){
  let idx1:number = content.indexOf('declare module Laya ');
  if(idx1 != -1){
    let temp:string = content.substring(idx1);
    let idx2:number = temp.indexOf('class ');
    while(idx2 != -1){
      let idx3:number = temp.indexOf('}', idx2);

      let checkIdx:number = temp.lastIndexOf('\n', idx2);
      let checkStr:string = temp.substring(checkIdx, idx2);
      if(checkStr.trim() != ''){
        idx2 = temp.indexOf('class ', idx2 + 6);
        continue;
      }
      //查询测试了下，没有意外。
      // let idx4:number = temp.lastIndexOf('\n', idx3);
      // let str:string = temp.substring(idx4, idx3);
      // console.log('saveLibVars1,', str);
      // console.log('saveLibVars1,', str.trim());

      let clsTemp:string = temp.substring(idx2, idx3 + 1);
      let clsStr:string = clsTemp.substring(0, clsTemp.indexOf('\n'));
      let fatherName:string = '';
      if(clsStr.indexOf(' extends ') != -1){
        fatherName = clsStr.split(' extends ')[1];
        fatherName = fatherName.split(' ')[0];
      }
      clsStr = clsStr.split('class ')[1];
      let clsName:string = clsStr.split(' ')[0];
      if(fileDataArr[clsName] == null){
        fileDataArr[clsName] = {isLaya:true, father:fatherName, var:[], fun:[], statics:[], content:clsTemp, classArr:[clsName]};
      }
      var obj:any = fileDataArr[clsName];

      let len:number = clsTemp.length;
      let index1:number = clsTemp.indexOf('\n', 6);
      let index2:number = clsTemp.indexOf('\n', index1 + 1);

      while(index2 != -1 && index2 < len - 10){
        let lineStr:string = clsTemp.substring(index1 + 1, index2);
        if(lineStr.match("(?=.*[a-zA-Z].*)")){
          // let idx44:number = lineStr.indexOf('public ');
          // let idx55:number = lineStr.indexOf('protected ');

          // if(idx44 != -1 || idx55 != -1){
            // let isClsFun:boolean = true;
            // if(!isClsFun){
              // console.log(isClsFun);
              if(lineStr.indexOf('*') == -1 && lineStr.indexOf('@en') == -1 && lineStr.indexOf('@zh') == -1){
                let khIdx:number = lineStr.indexOf('(');
                if(khIdx != -1){//是函数
                  let getidx:number = lineStr.indexOf(' get ');
                  if(getidx == -1 && lineStr.indexOf(' set ') == -1){//普通方法
                    if(lineStr.indexOf('constructor') == -1){
                      lineStr = lineStr.replace(/\s+/g, '$');
                      lineStr = lineStr.substring(0, lineStr.indexOf('('));
                      if(lineStr.charAt(lineStr.length - 1) == '>'){//说明是：addChild<T extends Node>(child: T): T;
                        lineStr = lineStr.substring(0, lineStr.indexOf('<'));
                      }
                      let arr1:string[] = lineStr.split('$');
                      let vname:string = arr1[arr1.length - 1];
                      vname = vname.trim();
                      if(lineStr.indexOf('static') != -1){
                        obj.statics.push(vname);
                      }
                      else{
                        obj.fun.push(vname);
                      }
                    }
                  }
                  else{//get,set方法
                    if(getidx != -1){
                      lineStr = lineStr.substring(0, lineStr.indexOf('('));
                      let arr2:string[] = lineStr.split(' ');
                      let vname:string = arr2[arr2.length - 1];
                      vname = vname.trim();
                      if(vname == ''){
                        console.log('空变量调试1：',clsName);
                      }
                      if(lineStr.indexOf('static') != -1){
                        obj.statics.push(vname);
                      }
                      else{
                        obj.var.push(vname);
                      }
                    }
                  }
                }
                else{//变量
                  lineStr = lineStr.replace(/\s+/g, '$');
                  let mhIdx:number = lineStr.indexOf(':');
                  if(mhIdx == -1){
                    mhIdx = lineStr.indexOf(';');
                  }
                  if(mhIdx != -1){
                    lineStr = lineStr.substring(0, mhIdx);
                    let arr3:string[] = lineStr.split('$');
                    let vname:string = arr3[arr3.length - 1];
                    vname = vname.trim();
                    if(vname == ''){
                      console.log('空变量调试2：',clsName);
                    }
                    if(lineStr.indexOf('static') != -1){
                      obj.statics.push(vname);
                    }
                    else{
                      obj.var.push(vname);
                    }
                  }
                }
              }
              // console.log('包含', lineStr);
            // }
          // }
        }
        index1 = clsTemp.indexOf('\n', index1 + 1);
        index2 = clsTemp.indexOf('\n', index1 + 1);
      }
      console.log(clsName + '--->', obj);
      idx2 = temp.indexOf('class ', idx3);
    }
  }
}
function onExeClick(){
  let inputValue:string = input.value;
  inputValue = inputValue.replace(/\\/g, '/');
  console.log('加载-------------------------->', inputValue);
  traverseDirectory(inputValue);
}
function onFindVars(){
  console.log('开始解析-------------------------->', fileTxtArr.length);
  for(var i=0; i<fileTxtArr.length; i++){
    saveVarNames(fileTxtArr[i].path, fileTxtArr[i].content);
  }
}
function onTestClick(){
  console.log('开始转换-------------------------->', fileTxtArr.length);

  isRunning = true;
  fileCount = fileTxtArr.length;
}
async function traverseDirectory(dir:string) {
  await fs.readdir(dir, (err:object, files:any) => {
    if (err) throw err;
    files.forEach((file: any) => {
      const filePath = path.join(dir, file);
      fs.stat(filePath, async (err:any, stats:any) => {
        if (err) throw err;
        if (stats.isDirectory()) {
          traverseDirectory(filePath);
        } else {

          if(filePath.indexOf('layaUI') == -1){
            console.log(filePath);
            // fileArr.push(filePath);

            await fs.readFile(filePath, 
                // 读取文件完成时调用的回调函数
                function(err:any, data:any) {  
                    if (err) throw err; 
                    // 数据是包含文件内容的缓冲区
                    var content:string = data.toString('utf8');
                    fileTxtArr.push({path:filePath, content:content});
                    
            });
          }
          
        }
      });
    });
  });
}
function saveVarNames(path:string, content:string):void{
  
  
  let inputValue:string = input.value;
  inputValue = inputValue.replace(/\\/g, '/');

  path = path.replace(/\\/g, '/');
  path = path.replace(inputValue, '');
  path = path.replace('/', '');
  path = path.replace('\.as', '');//最终结果是这样的：app/SelectRoleMain,RockerManager
  // console.log('path-------->', path);
  if(path.indexOf('NetChar') != -1){
    console.log('解析变量调试-------->', path);
  }
  
  let arr:string[] = path.split('/');
  let className:string = arr[arr.length - 1];
  className = className.replace('\.as', '');

  //查找所有class，并不能偷懒。
  let classArr:string[] = [];
  let clsStart:number = 0;
  let clsIdx:number = content.indexOf('class ', clsStart);
  while(clsIdx != -1){
    let clsEnd1:number = content.indexOf(' ', clsIdx + 6);
    let clsEnd2:number = content.indexOf('\r', clsIdx + 6);
    let clsEnd:number = Math.min(clsEnd1, clsEnd2);
    var clsName:string = content.substring(clsIdx + 6, clsEnd);
    classArr.push(clsName);

    clsStart = clsIdx + 6;
    clsIdx = content.indexOf('class ', clsStart);
  }

  if(fileDataArr[path] == null){
    fileDataArr[path] = {var:[], fun:[], statics:[], local:{}, content:content, classArr:classArr};
  }
  var obj:any = fileDataArr[path];

  let len:number = content.length;
  let index1:number = content.indexOf('public class ');
  index1  = content.indexOf('\n', index1 + 10);
  // index1  = content.indexOf('\n', index1 + 1);
  let index2:number = content.indexOf('\n', index1 + 1);
  let lineCount:number = 0;
  while(index2 != -1 && index2 < len - 10){

    lineCount ++;
    let lineStr:string = content.substring(index1 + 1, index2);
    if(lineStr.match("(?=.*[a-zA-Z].*)")){
      let idx1:number = lineStr.indexOf('public ');
      let idx2:number = lineStr.indexOf('private ');
      let idx3:number = lineStr.indexOf('protected ');
      let idx4:number = lineStr.indexOf('class ');
      if(idx1 != -1 || idx2 != -1 || idx3 != -1 || idx4 != -1){
        let isClsFun:boolean = false;
        for(var j=0; j<classArr.length; j++){
          if(lineStr.indexOf('public function ' + classArr[j]) != -1){
            isClsFun = true;
            break;
          }
        }
        if(!isClsFun){
          if(lineStr.indexOf('var ') != -1 || lineStr.indexOf('const ') != -1){
            // 定义正则表达式，匹配所有字母
            var regex = /[a-zA-Z]/g;
            // 使用 matchAll 方法找到所有匹配项
            var matches = lineStr.matchAll(regex);
            // 存储匹配项的索引
            const indices = [];
            let index:number = 0;
            for (const match of matches) {
                // 每个 match 是一个数组，其中第一个元素是匹配的文本，第二个元素是匹配的索引
                index = match.index;//找到字母开始的索引
                break;
            }
            let leftStr:string = lineStr.substring(0, index);
            regex = /\t/g;
            matches = leftStr.matchAll(regex);
            let count:number = 0;
            for (const match of matches) {
              count ++;
            }
            if(count < 3){//说明是成员变量、或者成员函数
              if(lineStr.indexOf('var ') != -1){
                let arr:string[] = lineStr.split('var ');
                let arr2:string[] = arr[1].split(':');
                let varName:string = arr2[0];
                varName = varName.trim();
                if(lineStr.indexOf('static var ') != -1){
                  obj.statics.push(varName);
                }
                else{
                  obj.var.push(varName);
                }
              }
              else{
                let arr:string[] = lineStr.split('const ');
                let arr2:string[] = arr[1].split(':');
                let varName:string = arr2[0];
                varName = varName.trim();
                if(lineStr.indexOf('static const ') != -1){
                  obj.statics.push(varName);
                }
                else{
                  obj.var.push(varName);
                }
              }
            }
          }
          else{
            //get函数
            let getIndex:number = lineStr.indexOf('function get ');
            if(getIndex != -1){
              let arr:string[] = lineStr.split('function get ');
              let arr2:string[] = arr[1].split('(');
              let varName:string = arr2[0];
              varName = varName.trim();
              if(lineStr.indexOf('static function') != -1){
                obj.statics.push(varName);
              }
              else{
                obj.var.push(varName);
              }
            }
            else{
              //函数成员
              getIndex = lineStr.indexOf('function ');
              if(getIndex != -1){
                let arr:string[] = lineStr.split('function ');
                let arr2:string[] = arr[1].split('(');
                let varName:string = arr2[0];
                varName = varName.trim();
                if(lineStr.indexOf('static function') != -1){
                  obj.statics.push(varName);
                }
                else{
                  obj.fun.push(varName);
                }
              }
            }
          }
          // console.log('包含', lineStr);
          
        }
      }
      else{//局部变量，用于模糊判断。就是补丁
        
      }
      ///
      let leftCount:number = getLeftSpace(lineStr);
      if(leftCount >= 3 || lineStr.indexOf('function ') != -1){
        let endIndex:number = matchBraces(lineStr, 0);
        let startIndex = lineStr.indexOf('{', 0);
        let lIdx1:number = lineStr.indexOf(':');
        while(lIdx1 != -1){
          if(endIndex != -1 && startIndex != -1){
            if(lIdx1 > startIndex && lIdx1 < endIndex){//检测是否在{...}内
              lIdx1 = lineStr.indexOf(':', lIdx1 + 4);
              continue;
            }
          }
          let tstr:string = lineStr.substring(lIdx1 - 1, lIdx1);
          if(tstr.match("(?=.*[a-zA-Z].*)")){
            let vsidx1:number = lineStr.lastIndexOf(' ', lIdx1);
            let vsidx2:number = lineStr.lastIndexOf(',', lIdx1);
            let vsidx3:number = lineStr.lastIndexOf('(', lIdx1);
            let vsidx:number = Math.max(vsidx1, vsidx2, vsidx3);
            let lvar:string = lineStr.substring(vsidx+1, lIdx1);

            lvar = lvar.trim();
            if(obj.local[lineCount] == null){
              obj.local[lineCount] = [];
            }
            let localArr:any[] = obj.local[lineCount];
            localArr.push({var:lvar, left:leftCount});
          }

          lIdx1 = lineStr.indexOf(':', lIdx1 + 4);
        }
      }
      ///
    }
    else{
      // console.log('不包含', lineStr);
    }
    // if(path.indexOf('RockerManager') != -1){
    //   console.log('linestr-->',lineStr);
    // }

    index1 = content.indexOf('\n', index1 + 1);
    index2 = content.indexOf('\n', index1 + 1);
    
    // console.log('00000000--->', index1, index2, len - 10);
  }
  console.log('vars---->', path, obj);

  //默认包下的类，在这里做个记录存储，后续用于 导包。
  //do something....
  
}
function getLeftSpace(lineStr:string):number{
  // 定义正则表达式，匹配所有字母
  var regex = /[a-zA-Z]/g;
  // 使用 matchAll 方法找到所有匹配项
  var matches = lineStr.matchAll(regex);
  let index:number = 0;
  for (const match of matches) {
      // 每个 match 是一个数组，其中第一个元素是匹配的文本，第二个元素是匹配的索引
      index = match.index;//找到字母开始的索引
      break;
  }
  let leftStr:string = lineStr.substring(0, index);
  regex = /\t/g;
  matches = leftStr.matchAll(regex);
  let count:number = 0;
  for (const match of matches) {
    count ++;
  }
  return count;
}

  
</script>

<style scoped>

.page{
  position:absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-start; /* 垂直方向上的对齐方式为左对齐 */
  justify-content: flex-start; /* 水平方向上的对齐方式为左对齐 */
  border: 2px solid red;
  box-sizing: border-box;
}
.div{
  position:relative;
  width: 100%;
  margin-top: 20px;
}
.text{
  position:relative;
  width: 100px !important;
  height: 40px !important;
  border: 1px solid blue;
}
header {
  line-height: 1.5;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}
</style>
